#pragma once
#pragma pack(1)

#include "pch.h"
#ifndef NETWORK_TRAFFIC_PROCESSING_V2_HEADERS_H
#define NETWORK_TRAFFIC_PROCESSING_V2_HEADERS_H


// 自定义公共数据类
class ShareDataClzz { // 多线程共享的数据
public:
    ShareDataClzz(ntp::IniReader *p_inicfg) : pInicfg(p_inicfg) {
    }

    ~ShareDataClzz() {}

public:
    ntp::IniReader* pInicfg;

    // 自定义结构体
    struct shareData{
        std::string tf_info; // 流量信息
        std::string tf; // 流量信息
    } sd;
    std::queue<shareData> data_queue1;
    std::queue<shareData> data_queue2;
    const size_t max_queue_size = 1024;

    // 同步用的对象
    std::mutex mtx;
    std::mutex mtx2;
    std::condition_variable cv_producer1, cv_producer2, cv_consumer;
};


// ====================================================== tcp/ip 协议数据结构 ↓↓↓↓↓↓
class FrameHeader
{
public:
    FrameHeader(const uint8_t* pkt_data) {
        p_ethhdr = (FramHeader_t*)malloc(sizeof(FramHeader_t));
        memset(p_ethhdr, 0, sizeof(FramHeader_t));
        memcpy(p_ethhdr, (uint8_t*)pkt_data, sizeof(FramHeader_t));

        FrameType = p_ethhdr->FrameType;

        FrameHeader_len = sizeof(FramHeader_t);

        //printf("FrameHeader Dst MAC addr:");
        //for (uint64_t i = 1; (i < sizeof(p_ethhdr->DstMAC) + 1); i++) {
        //    printf("%.2x ", p_ethhdr->DstMAC[i - 1]);
        //}
        //printf("\n");

        //printf("FrameHeader Src MAC addr:");
        //for (uint64_t i = 1; (i < sizeof(p_ethhdr->SrcMAC) + 1); i++) {
        //    printf("%.2x ", p_ethhdr->SrcMAC[i - 1]);
        //}
        //printf("\n");
    }

    ~FrameHeader()
    {
        if (p_ethhdr) {
            free(p_ethhdr);
        }
    }

    uint16_t FrameType{0};

    uint32_t FrameHeader_len{ 0 };

private:
    struct FramHeader_t {
        uint8_t DstMAC[6]; //目的MAC地址
        uint8_t SrcMAC[6]; //源MAC地址
        uint16_t FrameType;    //帧类型
    };
    FramHeader_t* p_ethhdr{nullptr};
};

class IPv4Header : FrameHeader
{
public:
    IPv4Header(const uint8_t* pkt_data) : FrameHeader(pkt_data)
    {
        if (FrameType == 0x0008 && FrameHeader_len != 0) {
            p_ip4_hdr = (IPv4Header_t*)malloc(sizeof(IPv4Header_t));
            memset(p_ip4_hdr, 0, sizeof(IPv4Header_t));
            memcpy(p_ip4_hdr, (uint8_t*)pkt_data + FrameHeader_len, sizeof(IPv4Header_t));

            Protocol = p_ip4_hdr->Protocol;
            IPV4_TotalLen = read_uint16((uint8_t*)pkt_data + FrameHeader_len + 2);

            for (uint64_t i = 0, j = FrameHeader_len + 12; i < 4; i++, j++) {
                if (i < 3) {
                    SrcIP += std::to_string((uint8_t)pkt_data[j]) + ".";
                }
                else {
                    SrcIP += std::to_string((uint8_t)pkt_data[j]);
                }
            }
            for (uint64_t i = 0, j = FrameHeader_len + 16; i < 4; i++, j++) {
                if (i < 3) {
                    DstIP += std::to_string((uint8_t)pkt_data[j]) + ".";
                }
                else {
                    DstIP += std::to_string((uint8_t)pkt_data[j]);
                }
            }

            IPv4Header_len += FrameHeader_len + sizeof(IPv4Header_t);

        }
        else {
            IPv4Header_len = 0;
        }
    }

    ~IPv4Header()
    {
        if (p_ip4_hdr) {
            free(p_ip4_hdr);
        }
    }

    std::string SrcIP{ "" };
    std::string DstIP{ "" };

    uint8_t Protocol{0};
    uint16_t IPV4_TotalLen { 0 };

    uint32_t IPv4Header_len{ 0 };

private:
    struct IPv4Header_t {
        uint8_t Ver_HLen;       //版本+报头长度
        uint8_t TOS;            //服务类型
        uint16_t TotalLen;      //总长度
        uint16_t ID;            //标识
        uint16_t Flag_Segment;  //标志+片偏移
        uint8_t TTL;            //生存周期
        uint8_t Protocol;       //协议类型
        uint16_t Checksum;      //头部校验和
        uint32_t SrcIP;         //源IP地址   十进制转成十六进制后 大小端转换，按字节转十进制
        uint32_t DstIP;         //目的IP地址
    };
    IPv4Header_t* p_ip4_hdr{ nullptr };
};

class UDPHeader
{
public:
    UDPHeader(const uint8_t* pkt_data, uint32_t offset)
    {
        p_udp_hdr = (UDPHeader_t*)malloc(sizeof(UDPHeader_t));
        memset(p_udp_hdr, 0, sizeof(UDPHeader_t));
        memcpy(p_udp_hdr, (uint8_t*)pkt_data + offset, sizeof(UDPHeader_t));

        SrcPort = read_uint16((uint8_t*)pkt_data + offset);
        DstPort = read_uint16((uint8_t*)pkt_data + offset + 2);
        UDP_HeaderLen = read_uint16((uint8_t*)pkt_data + offset + 4);

        UDPHeader_len += offset + sizeof(UDPHeader_t);
    }

    ~UDPHeader()
    {
        if (p_udp_hdr) {
            free(p_udp_hdr);
        }
    }

    uint16_t SrcPort{ 0 };
    uint16_t DstPort{ 0 };
    uint16_t UDP_HeaderLen{ 0 };

    uint32_t UDPHeader_len{ 0 };

private:
    struct UDPHeader_t {
        uint16_t SrcPort;    // 源端口号
        uint16_t DstPort;    // 目的端口号
        uint16_t len;        // 数据包长度
        uint16_t checkSum;   // 校验和
    };
    UDPHeader_t* p_udp_hdr{ nullptr };
};

class TCPHeader
{
public:
    TCPHeader(const uint8_t* pkt_data, uint32_t offset)
    {
        p_tcp_hdr = (TCPHeader_t*)malloc(sizeof(TCPHeader_t));
        memset(p_tcp_hdr, 0, sizeof(TCPHeader_t));
        memcpy(p_tcp_hdr, (uint8_t*)pkt_data + offset, sizeof(TCPHeader_t));

        if (p_tcp_hdr->HeaderLen == 128) {
            TCP_HeaderLen = 32;
            TCPHeader_len += 12;
        }
        else if (p_tcp_hdr->HeaderLen == 80) {
            TCP_HeaderLen = 20;
        }
        else {
            TCPHeader_len = 0;
            return;
        }

        SrcPort = read_uint16((uint8_t*)pkt_data + offset);
        DstPort = read_uint16((uint8_t*)pkt_data + offset + 2);
        SequenceNum = read_uint32((uint8_t*)pkt_data + offset + 4);

        TCPHeader_len += offset + sizeof(TCPHeader_t);
    }

    ~TCPHeader()
    {
        if (p_tcp_hdr) {
            free(p_tcp_hdr);
        }
    }

    uint16_t SrcPort{ 0 };
    uint16_t DstPort{ 0 };
    uint32_t SequenceNum{ 0 };
    uint8_t TCP_HeaderLen{ 0 };

    uint32_t TCPHeader_len{ 0 };

private:
    struct TCPHeader_t {
        uint16_t SrcPort;//源端口
        uint16_t DstPort;//目的端口
        uint32_t SeqNO;//序号
        uint32_t AckNO; //确认号
        uint8_t HeaderLen; //数据报头的长度(4 bit) + 保留(4 bit) 待确认
        uint8_t Flags; //标识TCP不同的控制消息
        uint16_t Window; //窗口大小
        uint16_t Checksum; //校验和
        uint16_t UrgentPointer;  //紧急指针
    };
    TCPHeader_t* p_tcp_hdr{ nullptr };
};

// ====================================================== tcp/ip 协议数据结构 ↑↑↑↑↑↑

#endif // NETWORK_TRAFFIC_PROCESSING_V2_HEADERS_H
